###############################################################################
#
# Copyright (c) 2011 Rainmaker Entertainment
# All Rights Reserved.
#
# This file contains unpublished confidential and proprietary
# information of Rainmaker Entertainment.  The contents of this file
# may not be copied or duplicated, in whole or in part, by any
# means, electronic or hardcopy, without the express prior
# written permission of Rainmaker Entertainment.
#
#    $HeadURL: http://pt/src/trunk/maya/rnkAssetChecks/core.py $
#    $Revision: 65282 $
#    $Author: nkoubi $
#    $Date: 2013-06-17 10:53:00 -0700 (Mon, 17 Jun 2013) $
#
###############################################################################

###############################################################################
## INFOS
###############################################################################

# Functions to be used by different checks


###############################################################################
## MODULES
###############################################################################

import traceback

try :
    import maya.cmds as cmds
    import maya.OpenMaya as OpenMaya
except :
    traceback.print_exc()
    print "Can't load Maya modules."
    
import re
        


###############################################################################
## FUNCTIONS
###############################################################################  

def listShapes(rootNode=None, types=["mesh", "nurbsSurface"]):
    """ 
    @brief List geometry shapes under the given root node.
    @return : List
    
    ARGS :
            @param rootNode - String - Root node name.
            @param types - List - Type of shapes to look for.
    """
    
    nodes = list()
    
    if rootNode and cmds.listRelatives(rootNode, allDescendents=True, type=types, path=True):
        nodes = [x for x in cmds.listRelatives(rootNode, allDescendents=True, type=types, path=True) if not cmds.getAttr('%s.intermediateObject' % x)]
    else:
        nodes = [x for x in cmds.ls(type=types) if not cmds.getAttr('%s.intermediateObject' % x)]
        
    return nodes


def walkDag(node):
    """ 
    @brief Walk trough a hierarchy and return the full path name of every node under the given root node.
    @return : List
    
    ARGS :
            @param node - String - Root node to get the hierarchy of.
    """
    
    result = []
    nodeMObj = asMObject(node)
    
    iter = OpenMaya.MItDag()
    iter.reset(nodeMObj)
    
    while not iter.isDone():
        
        dagPath = OpenMaya.MDagPath()
        iter.getPath(dagPath)
        
        result.append( dagPath.fullPathName() )
        
        iter.next()
        
        
    return result



def asMObject(node):
    """ 
    @brief Convert a node to an MObject.
    @return : MObject
    
    ARGS :
            @param node - String - Name of the node to convert.
    """
    
    sel = OpenMaya.MSelectionList()
    nodeMObj = OpenMaya.MObject()
    sel.add(node)
    sel.getDependNode(0, nodeMObj)
    
    return nodeMObj



def isTransform(node):
    """ 
    @brief Check if the given node is a transform
    @return : Bool
    
    ARGS :
            @param node - String - Name of the node to check.
    """
    
    nodeMObj = asMObject(node)
    
    return (nodeMObj.hasFn(OpenMaya.MFn.kTransform) or nodeMObj.hasFn(OpenMaya.MFn.kPluginEmitterNode))



def listRenderableShapes(rootNode):
    """ 
    @brief List all geometry nodes under a given root node that will be rendered.
    @return : List
    
    ARGS :
            @param rootNode - String - Root node to check the geometries from.
    """
    
    result = []
    
    geoList = cmds.ls(rootNode, dag=True, long=True, type=['mesh', 'nurbsSurface'])
    # Exclude nodes whose transform parent names end with '_EX'
    if not len(geoList) == 0 :
        for shape in geoList :
            transform = cmds.listRelatives(shape, parent=True)[0]
            if transform.endswith('_EX') is False :
                result.append(shape)

    return result


def deleteNamespaces():
    """ 
    @brief Check if any non-referenced DG have a namespace.If yes, remove it.
    @return : Nothing
    """
    
    allRefFiles = cmds.file(q=True, reference=True)
    allNamespaces = cmds.namespaceInfo(listOnlyNamespaces=True)
    excludeNamespaces = ['UI', 'shared']
    
    ## Get all reference name of ref files
    if not len(allRefFiles) == 0 :
        for eachFile in allRefFiles :
            excludeNamespaces.append( str(cmds.file(eachFile, q=True, namespace=True)) )
            
            
    removeNamespaces = list( set(allNamespaces).difference(set(excludeNamespaces)) )
    if not len(removeNamespaces) == 0 :
        for each in removeNamespaces :
            cmds.namespace(force=True, moveNamespace=[each, ':'])


    
def detectEyeBall(nodeName):
    """ 
    @brief Check if the given node is an eyeBall one.
    @return : Bool
    
    ARGS :
            @param nodeName - String - Node to check.
    """
    
    if cmds.attributeQuery('__rnkmiSingleFPupilRadius', node=nodeName, exists=True):
        return True
    else:
        return False
    
    
    
def convertIdRangeToIdList(componentRangeList, **kwargs):
    """ 
    @brief Convert an id range to an id list (Example: [1:4] to [1, 2, 3, 4]).
    @return: List of ints
    
    ARGS :
            @param componentRangeList - List (['Int:Int', 'Int:Int']) - List of components ranges or if the kwarg convertFromSel is True, the output of cmds.ls(flatten=True).
    
    KWARGS :
            @param convertFromSel - Boolean - Set it to True if you pass the output of cmds.ls(flatten=True) as the componentRangeList arg.
            @param selType - String (face/vertex/edge) - if convertFromSel is True, give the type of selection passed in.
    """
    
    convertFromSel = kwargs.get('convertFromSel', False)
    selType = kwargs.get('selType', 'face')
    
    idList = []
    for eachRange in iter(componentRangeList) :
        if convertFromSel is True :
            if selType == 'face' :
                eachRange = re.findall(r"\.f[[]+([\d*:\d*]+)[]]", eachRange, re.I)[0]
            elif selType == 'vertex' :
                eachRange = re.findall(r"\.vtx[[]+([\d*:\d*]+)[]]", eachRange, re.I)[0]
            elif selType == 'edge' :
                eachRange = re.findall(r"\.e[[]+([\d*:\d*]+)[]]", eachRange, re.I)[0]
                
        splitRange = re.split(":", eachRange, re.I)
        if len(splitRange) == 1 :
            idList += [int(splitRange[0])]
        else :
            idList += xrange(int(splitRange[0]), int(splitRange[1])+1)
            
            
    return idList
